﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LarDosIdosos.Business.Model;
using LarDosIdosos.NewAcessaDados;
using MySql.Data.MySqlClient;

namespace LarDosIdosos.Business
{
    public class DBEstoque
    {
        private string _stringConnection;

        public DBEstoque(string stringDeConexaoComBanco)
        {
            _stringConnection = stringDeConexaoComBanco;
        }

        /// <summary>
        /// Busca uma lista de entrada de produtos pela query recebida
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<EntradaProduto> SelectEntradaList(string sql)
        {
            AcessaDados conn = new AcessaDados(_stringConnection);
            try
            {
                conn.OpenConnection();
                var reader = conn.ExecuteDataReader(sql);
                if (reader.HasRows)
                {
                    return MontaListaDeEntrada(reader);
                }
                return new List<EntradaProduto>();
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível consultar o tipo documento", ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }

        /// <summary>
        /// Monta uma lista de entrada de produtos pelo reader recebido
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private List<EntradaProduto> MontaListaDeEntrada(MySqlDataReader reader)
        {
            List<EntradaProduto> listEntrada = new List<EntradaProduto>();
            while (reader.Read())
            {
                listEntrada.Add(MontaEntrada(reader));
            }
            return listEntrada;
        }

        /// <summary>
        /// Monta uma lista de saida pelo reader recebido
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private List<SaidaProduto> MontaListaDeSaida(MySqlDataReader reader)
        {
            List<SaidaProduto> listSaida = new List<SaidaProduto>();
            while (reader.Read())
            {
                listSaida.Add(MontaSaida(reader));
            }
            return listSaida;
        }

        /// <summary>
        /// Monta um produto de entrada
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private EntradaProduto MontaEntrada(MySqlDataReader reader)
        {
            EntradaProduto estoque = new EntradaProduto();
            estoque.Codigo_Entrada = Convert.ToInt32(reader["Codigo_Entrada"]);
            estoque.Quantidade = Convert.ToDouble(reader["quantidade_entrada"]);
            estoque.Data_Entrada = Convert.ToDateTime(reader["data_entrada"]);
            estoque.Is_Doacao = Convert.ToBoolean(reader["Is_doacao"]);
            estoque.Parceiro = ObtemParceiro(reader["Parceiro_Codigo_Parceiro"].ToString());
            estoque.Idoso = ObtemIdoso(reader["idoso_codigo_idoso"].ToString());
            estoque.FuncionarioEntradaProduto = ObtemFuncionario(Convert.ToInt32(reader["funcionario_codigo_funcionario"]));

            estoque.Produto.Codigo_Produto = Convert.ToInt32(reader["codigo_produto"]);
            estoque.Produto.Nome_Produto = reader["nome_produto"].ToString();
            estoque.Produto.Tipo_Produto.Codigo_Tipo_Produto = Convert.ToInt32(reader["codigo_tipo_produto"]);
            estoque.Produto.Tipo_Produto.Nome_Tipo_Produto = reader["Nome_tipo_produto"].ToString();
            estoque.Produto.Unidade_De_Medida.Codigo_Unidade_De_Medida = Convert.ToInt32(reader["codigo_unidade_de_medida"]);
            estoque.Produto.Unidade_De_Medida.Nome_Unidade_De_Medida = reader["Nome_Unidade_De_Medida"].ToString();
            estoque.Produto.Unidade_De_Medida.Sigla_Unidade_De_Medida = reader["Sigla_Unidade_De_Medida"].ToString();
            return estoque;
        }

        /// <summary>
        /// Monta um produto de saída
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private SaidaProduto MontaSaida(MySqlDataReader reader)
        {
            SaidaProduto saidaProduto = new SaidaProduto();
            saidaProduto.Codigo_Saida = Convert.ToInt32(reader["codigo_saida"]);
            saidaProduto.Data_Saida = Convert.ToDateTime(reader["data_saida"]);
            saidaProduto.FuncionarioSaidaProduto = ObtemFuncionario(Convert.ToInt32(reader["funcionario_codigo_funcionario"]));
            saidaProduto.Quantidade = Convert.ToDouble(reader["quantidade_saida"]);
            saidaProduto.Produto.Codigo_Produto = Convert.ToInt32(reader["codigo_produto"]);
            saidaProduto.Produto.Nome_Produto = reader["nome_produto"].ToString();
            saidaProduto.Produto.Tipo_Produto.Codigo_Tipo_Produto = Convert.ToInt32(reader["codigo_tipo_produto"]);
            saidaProduto.Produto.Tipo_Produto.Nome_Tipo_Produto = reader["Nome_tipo_produto"].ToString();
            saidaProduto.Produto.Unidade_De_Medida.Codigo_Unidade_De_Medida = Convert.ToInt32(reader["codigo_unidade_de_medida"]);
            saidaProduto.Produto.Unidade_De_Medida.Nome_Unidade_De_Medida = reader["Nome_Unidade_De_Medida"].ToString();
            saidaProduto.Produto.Unidade_De_Medida.Sigla_Unidade_De_Medida = reader["Sigla_Unidade_De_Medida"].ToString();
            return saidaProduto;
        }

        /// <summary>
        /// Busca um funcionário pelo código
        /// </summary>
        /// <param name="codigo_funcionario"></param>
        /// <returns></returns>
        private Funcionario ObtemFuncionario(int codigo_funcionario)
        {
            DBFuncionarios dbFuncionarios = new DBFuncionarios(_stringConnection);
            return dbFuncionarios.BuscaFuncionario(codigo_funcionario);
        }


        /// <summary>
        /// Busca um Idoso pelo codigo
        /// </summary>
        /// <param name="codigo_idoso"></param>
        /// <returns></returns>
        private Idoso ObtemIdoso(string codigo_idoso)
        {
            if (string.IsNullOrEmpty(codigo_idoso))
            {
                return new Idoso();
            }
            DBIdosos dbIdosos = new DBIdosos(_stringConnection);

            return dbIdosos.SelectIdoso("select * from idoso where codigo_idoso = " + codigo_idoso);
        }

        /// <summary>
        /// Busca um parceiro pelo código
        /// </summary>
        /// <param name="codigo_parceiro"></param>
        /// <returns></returns>
        private Parceiro ObtemParceiro(string codigo_parceiro)
        {
            if(string.IsNullOrEmpty(codigo_parceiro))
            {
                return new Parceiro{ Nome_Parceiro = "Anônimo"};
            }
            DBParceiro dbParceiro = new DBParceiro(_stringConnection);
            return dbParceiro.BuscaParceiro(Convert.ToInt32(codigo_parceiro));
        }

        /// <summary>
        /// miau para contar os registros
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int Count(string sql)
        {
            var conn = new AcessaDados(_stringConnection);
            try
            {
                int i = 0;
                conn.OpenConnection();
                var reader = conn.ExecuteDataReader(sql);
                while (reader.Read())
                {
                    i++;
                }
                return i;
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível consultar o tipo documento", ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }

        /// <summary>
        /// Busca uma entrada de produto pela query
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public EntradaProduto Select(string sql)
        {
            AcessaDados conn = new AcessaDados(_stringConnection);
            try
            {
                conn.OpenConnection();
                var reader = conn.ExecuteDataReader(sql);
                if (reader.Read())
                {
                    return MontaEntrada(reader);
                }
                return null;
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível consultar o tipo documento", ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }

        /// <summary>
        /// faz um update 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int Update(string sql)
        {
            AcessaDados conn = new AcessaDados(_stringConnection);
            try
            {
                conn.OpenConnection();
                int updated = conn.ExecuteNonQuery(sql);
                return updated;
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível executar a query: " + sql, ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }

        /// <summary>
        /// Faz um insert
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int Insert(string sql)
        {
            AcessaDados conn = new AcessaDados(_stringConnection);
            try
            {
                conn.OpenConnection();
                int updated = conn.ExecuteNonQuery(sql);
                return updated;
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível executar a query: " + sql, ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }

        /// <summary>
        /// Busca uma lista de produtos de saída
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<SaidaProduto> SelectSaidaList(string sql)
        {
            AcessaDados conn = new AcessaDados(_stringConnection);
            try
            {
                conn.OpenConnection();
                var reader = conn.ExecuteDataReader(sql);
                if (reader.HasRows)
                {
                    return MontaListaDeSaida(reader);
                }
                return new List<SaidaProduto>();
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível consultar o tipo documento", ex);
            }
            finally
            {
                conn.CloseConection();
            }
        }
    }
}
